<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Map and Bar Chart</title>
    <style>
        .rightBox {
            width: 40%;
            display: flex;
            flex-direction: column;
            align-items: center;
            text-align: center;
            justify-content: space-around;
        }

        #map,
        #bar_chart {
            width: 100%;
            height: 400px;
            flex: 1;
        }

        .tooltip {
            position: absolute;
            text-align: center;
            width: fit-content;
            padding: 10px;
            font: 12px sans-serif;
            font-weight: 800;
            background: white;
            border: 1px solid #333;
            border-radius: 5px;
            pointer-events: none;
            opacity: 0;
        }
    </style>
</head>

<body>

    <h1 style="text-align: center;">Map and Bar Chart</h1>

    <div class="rightBox">
        <div>
            <input type="number" id="yearInput" value="1800" min="1800" max="2100">
            <select id="attributeSelect">
                <option value="income">Income</option>
                <option value="population">Population</option>
                <option value="lifeExpectancy">Life Expectancy</option>
            </select>
        </div>

        <div id="map"></div>
        <div id="bar_chart"></div>
    </div>

    <script src="https://d3js.org/d3.v7.min.js"></script>
    <script src="https://d3js.org/topojson.v1.min.js"></script>
    <script src="https://d3js.org/d3-legend.v2.min.js"></script>
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.13.0/d3-legend.js"></script> -->
    <script src="../lib/d3-legend.js"></script>
    <script src="./mapping.js" type="module"></script>

    <script type="module">
        import { countryMap } from "./mapping.js";
        const countryMapping = countryMap;

        d3.csv('../data/newData.csv').then(data => {
            const tooltip = d3.select("body").append("div")
                .attr("class", "tooltip")
                .style("opacity", 0);

            function formatNumber(num) {
                if (num >= 1e9) {
                    return (num / 1e9).toFixed(1) + "B";
                } else if (num >= 1e6) {
                    return (num / 1e6).toFixed(1) + "M";
                } else if (num >= 1e3) {
                    return (num / 1e3).toFixed(1) + "k";
                } else {
                    return num.toFixed(1);
                }
            }

            function drawMap(year, selectedAttribute) {
                var filteredData = data.filter(d => d.year == year);

                filteredData.forEach(function (d) {
                    d.iso3 = countryMapping[d.name];
                });

                const dataMap = new Map(filteredData.map(d => [d.iso3, +d[selectedAttribute]]));

                const colorScale = d3.scaleSequential(d3.interpolateBlues)
                    .domain(d3.extent(filteredData, d => +d[selectedAttribute]));
                // https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson
                d3.json('../lib/world.geojson').then(function (geojson) {
                    geojson.features.forEach(function (d) {
                        d.properties[selectedAttribute] = dataMap.get(d.id) || 0;
                    });

                    const svg = d3.select("#map").html("").append("svg")
                        .attr("width", "100%")
                        .attr("height", 400);

                    const projection = d3.geoMercator()
                        .scale(100)
                        .translate([svg.node().clientWidth / 2, svg.node().clientHeight / 1.5]);

                    const path = d3.geoPath().projection(projection);

                    svg.append("g")
                        .selectAll("path")
                        .data(geojson.features)
                        .enter()
                        .append("path")
                        .attr("d", path)
                        .attr("fill", d => colorScale(d.properties[selectedAttribute]))
                        .attr("stroke", "#333")
                        .on("mouseover", function(event, d) {
                            tooltip.transition()
                                .duration(200)
                                .style("opacity", .9);
                            tooltip.html(d.properties.name + "<br/>" + selectedAttribute + ": " + formatNumber(d.properties[selectedAttribute]))
                                .style("left", (event.pageX) + "px")
                                .style("top", (event.pageY - 28) + "px");
                        })
                        .on("mouseout", function(d) {
                            tooltip.transition()
                                .duration(500)
                                .style("opacity", 0);
                        });

                    // Add legend
                    const legendSvg = svg.append("g")
                        .attr("class", "legendSequential")
                        .attr("transform", "translate(20,20)")
                        .attr("transform", `translate(20, ${svg.node().clientHeight - 150})`)
                        .style("font-size", "15px");

                    const legendSequential = d3.legendColor()
                        .shapeWidth(20)
                        .shapeHeight(20)
                        .cells(6)
                        .orient("vertical")
                        .labelFormat(formatNumber)
                        .scale(colorScale);

                    // 调整字体大小
                    legendSvg.call(legendSequential);
                });
            }

            function updateBarChart(year, attribute) {
                const filteredData = data.filter(d => d.year == year);

                const summedData = d3.rollup(filteredData, v => d3.sum(v, d => +d[attribute]), d => d.region);

                const dataArray = Array.from(summedData, ([key, value]) => ({ region: key, value }));

                const margin = { top: 10, right: 30, bottom: 100, left: 40 },
                    width = 460 - margin.left - margin.right,
                    height = 450 - margin.top - margin.bottom;

                const svg = d3.select("#bar_chart").html("").append("svg")
                    .attr("width", width + margin.left + margin.right)
                    .attr("height", height + margin.top + margin.bottom)
                    .append("g")
                    .attr("transform", `translate(${margin.left},${margin.top})`);

                const x = d3.scaleBand()
                    .range([0, width])
                    .domain(dataArray.map(d => d.region))
                    .padding(0.2);
                svg.append("g")
                    .attr("transform", `translate(0, ${height})`)
                    .call(d3.axisBottom(x))
                    .selectAll("text")
                    .attr("transform", "translate(-10,0)rotate(-45)")
                    .style("text-anchor", "end");

                const y = d3.scaleLinear()
                    .domain([0, d3.max(dataArray, d => d.value)])
                    .range([height, 0]);
                svg.append("g")
                    .call(d3.axisLeft(y).tickFormat(d => {
                        return formatNumber(d);
                    }));

                svg.selectAll("bar")
                    .data(dataArray)
                    .enter()
                    .append("rect")
                    .attr("x", d => x(d.region))
                    .attr("y", d => y(d.value))
                    .attr("width", x.bandwidth())
                    .attr("height", d => height - y(d.value))
                    .attr("fill", "#69b3a2")
                    .on("mouseover", function(event, d) {
                        tooltip.transition()
                            .duration(200)
                            .style("opacity", .9);
                        tooltip.html(d.region + "<br/>" + attribute + ": " + formatNumber(d.value))
                            .style("left", (event.pageX) + "px")
                            .style("top", (event.pageY - 28) + "px");
                    })
                    .on("mouseout", function(d) {
                        tooltip.transition()
                            .duration(500)
                            .style("opacity", 0);
                    });
            }

            var yearInput = document.getElementById('yearInput');
            var attributeSelect = document.getElementById('attributeSelect');
            yearInput.addEventListener('input', function () {
                var selectedYear = parseInt(yearInput.value);
                var selectedAttribute = attributeSelect.value;
                drawMap(selectedYear, selectedAttribute);
                updateBarChart(selectedYear, selectedAttribute);
            });
            attributeSelect.addEventListener('change', function () {
                var selectedYear = parseInt(yearInput.value);
                var selectedAttribute = attributeSelect.value;
                drawMap(selectedYear, selectedAttribute);
                updateBarChart(selectedYear, selectedAttribute);
            });

            drawMap(1800, 'income');
            updateBarChart(1800, 'income');
        });
    </script>
</body>

</html>
